//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Mapping Application Block
//===============================================================================

using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design.Validation;
using EntLibContrib.Mapping.Properties;

namespace EntLibContrib.Mapping.Configuration.Design
{
	/// <summary>
	/// Represents a mapping using an Xml data file.
	/// </summary>
	[Serializable]
	public sealed class SuperMapperNode : MapperNode
	{
		#region Fields
		private string domainObjectSuperTypeColumn;
		private List<SuperType> superTypes = new List<SuperType>();
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets the table column that holds references to the domain object <see cref="SuperType"/>s.
		/// </summary>
		/// <value>
		/// The column name.
		/// </value>
		[Required]
		[MappingCategory("CategoryProvider")]
		[MappingDescription("SuperMapperDomainObjectSuperTypeColumnDescription")]
		public string DomainObjectSuperTypeColumn
		{
			get { return domainObjectSuperTypeColumn; }
			set { domainObjectSuperTypeColumn = value; }
		}

		/// <summary>
		/// Gets the collection of super types.
		/// </summary>
		/// <value>
		/// Super type collection.
		/// </value>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
		[MappingCategory("CategoryProvider")]
		[MappingDescription("SuperMapperSuperTypesDescription")]
		public List<SuperType> SuperTypes
		{
			get { return superTypes; }
		}

		/// <summary>
		/// Gets a <see cref="SuperMapperData"/> configuration object using the node data.
		/// </summary>
		/// <value>
		/// A <see cref="SuperMapperData"/> configuration object using the node data.
		/// </value>
		[ReadOnly(true)]
		public override MapperBaseData MapperData
		{
			get 
			{ 
				SuperMapperData mapperData = new SuperMapperData(Name, TableName, domainObjectSuperTypeColumn);
				foreach (SuperType superType in SuperTypes)
				{
					mapperData.DomainObjectSuperTypes.Add(new SuperTypeData(superType.DataValue, superType.SuperTypeName));
				}

				return mapperData;
			}
		}
		#endregion

		#region Construction
		/// <summary>
		/// Initialize a new instance of the <see cref="SuperMapperNode"/> class.
		/// </summary>
		public SuperMapperNode ()
			: this(new SuperMapperData(InternalResources.DefaultSuperMapperNodeName, string.Empty, string.Empty))
		{
		}

		/// <summary>
		/// Initialize a new instance of the<see cref="SuperMapperNode"/> class with a <see cref="SuperMapperData"/> configuration object.
		/// </summary>
		/// <param name="mapperData">The mapper data.</param>
		public SuperMapperNode(SuperMapperData mapperData)
		{
			if (mapperData == null)
				throw new ArgumentNullException("mapperData");

			Rename(mapperData.Name);
			this.TableName = mapperData.TableName;
			this.domainObjectSuperTypeColumn = mapperData.DomainObjectSuperTypeColumn;
			foreach (SuperTypeData superTypeData in mapperData.DomainObjectSuperTypes)
			{
				superTypes.Add(new SuperType(superTypeData.Name, superTypeData.DomainObjectSuperTypeName));
			}
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Clones this instance.
		/// </summary>
		/// <returns></returns>
		public override MapperBaseNode Clone()
		{
			SuperMapperNode mapperNode = new SuperMapperNode((SuperMapperData)this.MapperData);
			foreach (ConfigurationNode mapNode in this.Nodes)
			{
				MapBaseNode node = mapNode as MapBaseNode;
				if (node != null)
				{
					MapBaseNode newMapNode = node.Clone();
					mapperNode.AddNode(newMapNode);
				}
			}
			return mapperNode;
		}
		#endregion
	}
}